package graphics.raytracing;

import static util.MatrixOperationsF.add;
import static util.MatrixOperationsF.arI;
import static util.MatrixOperationsF.cloo;
import static util.MatrixOperationsF.multiply;
import static util.MatrixOperationsF.negate;
import graphics.datastructures.Triangle;
public class SimpleWindow implements Window<Triangle> {
	private LightSource _source;
	private int _ymax;
	private int _xmax;
	private CameraPosition _camera;
	public SimpleWindow(float[] origin,float[] vx,float[] vy,int xmax,int ymax,LightSource source, CameraPosition camera)
	{
		_o=cloo(origin);
		_vx=cloo(vx);
		_vy=cloo(vy);
		content = new float[xmax][ymax][];
		_source=source;
		_xmax = xmax;
		_ymax = ymax;
		toreach = xmax*ymax;
		_camera=camera;
	}
	private float[] _o;//topleft
	private float[] _vx;//vector to the right
	private float[] _vy;//vector to the bottom
	private float[][][] content;
	private Object _lock="";
	private int colorc=0;
	private int toreach=0;
	private Shader _shader; 
	/* (non-Javadoc)
	 * @see graphics.raytracing.Window#determineRay(graphics.rasterizing.camera.CameraPosition, int, int)
	 */
	@Override
	public Ray determineRay(int x,int y)
	{
		float xperc = (float)x/(float)_xmax;
		float yperc = (float)y/(float)_ymax;
		float [] target= add(add(_o,multiply(_vy, yperc)),multiply(_vx, xperc));
		float[] direction = add(target,negate(_camera.getOrigin()));
		return new SimpleRay(_camera.getOrigin(),direction,1,_source,arI(x,y));
	}
	/* (non-Javadoc)
	 * @see graphics.raytracing.Window#getColor(int, int)
	 */
	@Override
	public float[] getColor(int x,int y)
	{
		return content[x][y];
	}
	@Override
	public synchronized void color(int i, int j, float[] color) {
		content[i][j]=cloo(color);
		colorc++;
		if(colorc==toreach)
			synchronized (_lock) {
				_lock.notify();
			}
	}
	/* (non-Javadoc)
	 * @see graphics.raytracing.Window#xy()
	 */
	@Override
	public int[] xy() {
		return arI(_xmax,_ymax);
	}
	/* (non-Javadoc)
	 * @see graphics.raytracing.Window#getView()
	 */
	@Override
	public float[][][] getView() {
		return content;
	}
	@Override
	public void waitForSet() {
		if(colorc==toreach)
			{
			
			return;
			}
		synchronized (_lock) {
			try {
				_lock.wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			}
	}
	@Override
	public float[] getCenter() {
		return add(_o,add(multiply(_vx, 1/2),multiply(_vy,1/2)));
	}
	@Override
	public void reset() {
		colorc=0;
	}
	
	@Override
	public void setShader(Shader s) {
		_shader=s;
		
	}
	@Override
	public void color(int[] _xy,CastResult result) {
		color(_xy[0], _xy[1], getShader().shade(result));
	}
	@Override
	public Shader getShader() {
		return _shader;
	}
}
